using System;
using System.Collections.Generic;
using System.Text;
using CodePlex.SpaceBlock.FS;

using Microsoft.VisualStudio.TestTools.UnitTesting;
using CodePlex.Resourceful.Amazon.S3;
using CodePlex.Resourceful;

namespace CodePlex.SpaceBlock.Test
{
    public static class StaticTests
    {

        public static string SecretAccessKey
        {
            get
            {
                return Environment.GetEnvironmentVariable("AWS").Split(':')[1];
            }
        }

        public static string AccessKeyID
        {
            get
            {
                return Environment.GetEnvironmentVariable("AWS").Split(':')[0];
            }
        }

      
        public static void SharedTests(ITaskRunner runner)
        {
            StaticTests.AbnormalTests(runner);
            //StaticTests.NormalTests(runner);
        }

        public static void AbnormalTests(ITaskRunner runner)
        {
            // s3delete

            bool rt = runner.RunTask("S3Delete"

            );
            Assert.IsFalse(rt);

            rt = runner.RunTask("S3Delete",
                new NameValue("DestinationPath","/asdf/small4.zip")
           );
            Assert.IsFalse(rt);

            rt = runner.RunTask("S3Delete",
                new NameValue("AccessKeyID", ""),
            new NameValue("SecretAccessKey", SecretAccessKey),
               new NameValue("DestinationPath", "/asdf/small4.zip")
          );
            Assert.IsFalse(rt);


            rt = runner.RunTask("S3Delete",
            new NameValue("AccessKeyID", "asdf"),
            new NameValue("SecretAccessKey", SecretAccessKey),
           new NameValue("DestinationPath", "/asdf/small4.zip")
      );
            Assert.IsFalse(rt);

            rt = runner.RunTask("S3Delete",
            new NameValue("AccessKeyID", AccessKeyID),
            new NameValue("SecretAccessKey", SecretAccessKey),
           new NameValue("DestinationPath", "///")
      );
            Assert.IsFalse(rt);




            // s3download

            rt = runner.RunTask("S3Download"

       );
            Assert.IsFalse(rt);

            rt = runner.RunTask("S3Download",
                 new NameValue("AccessKeyID", AccessKeyID),
            new NameValue("SecretAccessKey", SecretAccessKey),
           new NameValue("DestinationPath", @"c:\small_again.zip")
     );
            Assert.IsFalse(rt);


            rt = runner.RunTask("S3Download",
                new NameValue("AccessKeyID", AccessKeyID),
           new NameValue("SecretAccessKey", SecretAccessKey),
           new NameValue("SourcePath", "/asdf/doesntexist"),
          new NameValue("DestinationPath", @"c:\small_again.zip")
    );
            Assert.IsFalse(rt);

            rt = runner.RunTask("S3Download",
              new NameValue("AccessKeyID", AccessKeyID),
         new NameValue("SecretAccessKey", SecretAccessKey),
         new NameValue("SourcePath", "/asdf/"),
        new NameValue("DestinationPath", @"c:\small_again.zip")
  );
            Assert.IsFalse(rt);



            // s3upload

            rt = runner.RunTask("S3Upload"

       );
            Assert.IsFalse(rt);

            rt = runner.RunTask("S3Upload",
                 new NameValue("AccessKeyID", AccessKeyID),
            new NameValue("SecretAccessKey", SecretAccessKey),
           new NameValue("DestinationPath", "/asdf/small_again.zip")
     );
            Assert.IsFalse(rt);


            rt = runner.RunTask("S3Upload",
                new NameValue("AccessKeyID", AccessKeyID),
           new NameValue("SecretAccessKey", SecretAccessKey),
           new NameValue("SourcePath", @"c:\b\doesntexist"),
          new NameValue("DestinationPath", "/asdf/small_again.zip")
    );
            Assert.IsFalse(rt);

            rt = runner.RunTask("S3Upload",
              new NameValue("AccessKeyID", AccessKeyID),
         new NameValue("SecretAccessKey", SecretAccessKey),
         new NameValue("SourcePath", @"c:\b\"),
        new NameValue("DestinationPath", "/asdf/small_again.zip")
  );
            Assert.IsFalse(rt);


            rt = runner.RunTask("S3Upload",
           new NameValue("AccessKeyID", AccessKeyID),
      new NameValue("SecretAccessKey", SecretAccessKey),
      new NameValue("SourcePath", @"c:\small.zip"),
     new NameValue("DestinationPath", "/asdf/small_again.zip"),
     new NameValue("CannedACL","asdf")
);
            Assert.IsFalse(rt);





        }

        public static void NormalTests(ITaskRunner runner)
        {
            string accessKeyID = AccessKeyID;
            string secretAccessKey = SecretAccessKey;


            S3Connection connection = new S3Connection(accessKeyID, secretAccessKey, true, RequestStyle.Path);
            S3FileSystem fs = new S3FileSystem(connection);

            Path testDestinationPath = Path.Parse("/asdf/small.zip");
            string testSourcePath = @"C:\small.zip";

            System.IO.FileInfo testSourceFileInfo = new System.IO.FileInfo(testSourcePath);

            // normal upload
            bool rt = runner.RunTask("S3Delete",
             new NameValue("AccessKeyID", accessKeyID),
             new NameValue("SecretAccessKey", secretAccessKey),
             new NameValue("DestinationPath", testDestinationPath.ToString())
             );
            Assert.IsTrue(rt);
            
            Assert.IsFalse(fs.Exists(testDestinationPath));

            rt = runner.RunTask("S3Upload",
              new NameValue("AccessKeyID", accessKeyID),
              new NameValue("SecretAccessKey", secretAccessKey),
              new NameValue("SourcePath", testSourcePath),
              new NameValue("DestinationPath", testDestinationPath.ToString())
              );
            Assert.IsTrue(rt);

            //fs.Invalidate(Path.Parse("/asdf/"));
            IFileItem item = fs.GetItem(testDestinationPath) as IFileItem;
            Assert.IsNotNull(item);
            Assert.AreEqual(testSourceFileInfo.Length, item.Size);
            Metadata metadata = fs.GetMetadata(testDestinationPath);
            Assert.AreEqual("application/x-zip-compressed", metadata[HttpHeader.ContentType]);
            ACL acl = fs.GetACL(testDestinationPath);
            Assert.AreEqual(1, acl.Principals.Count);
            Assert.AreEqual(acl.Owner, acl.Principals[0]);
            ReadOnlyList<string> permissions = acl.GetPermissions(acl.Principals[0]);
            Assert.AreEqual(1, permissions.Count);
            Assert.AreEqual(S3Constants.Permissions.FullControl, permissions[0]);


            // normal upload with content-type
            rt = runner.RunTask("S3Delete",
                       new NameValue("AccessKeyID", accessKeyID),
                       new NameValue("SecretAccessKey", secretAccessKey),
                       new NameValue("DestinationPath", testDestinationPath.ToString())
                       );
            Assert.IsTrue(rt);
            //fs.Invalidate(Path.Parse("/asdf/"));
            Assert.IsFalse(fs.Exists(testDestinationPath));

            rt = runner.RunTask("S3Upload",
              new NameValue("AccessKeyID", accessKeyID),
              new NameValue("SecretAccessKey", secretAccessKey),
              new NameValue("SourcePath", testSourcePath),
              new NameValue("DestinationPath", testDestinationPath.ToString()),
              new NameValue("ContentType", "application/x-made-up")
              );
            Assert.IsTrue(rt);
            //fs.Invalidate(Path.Parse("/asdf/"));
            item = fs.GetItem(testDestinationPath) as IFileItem;
            Assert.IsNotNull(item);
            Assert.AreEqual(testSourceFileInfo.Length, item.Size);
            metadata = fs.GetMetadata(testDestinationPath);
            Assert.AreEqual("application/x-made-up", metadata[HttpHeader.ContentType]);
            acl = fs.GetACL(testDestinationPath);
            Assert.AreEqual(1, acl.Principals.Count);
            Assert.AreEqual(acl.Owner, acl.Principals[0]);
            permissions = acl.GetPermissions(acl.Principals[0]);
            Assert.AreEqual(1, permissions.Count);
            Assert.AreEqual(S3Constants.Permissions.FullControl, permissions[0]);




            // normal upload with acl
           rt = runner.RunTask("S3Delete",
                       new NameValue("AccessKeyID", accessKeyID),
                       new NameValue("SecretAccessKey", secretAccessKey),
                       new NameValue("DestinationPath", testDestinationPath.ToString())
                       );
           Assert.IsTrue(rt);
            //fs.Invalidate(Path.Parse("/asdf/"));
            Assert.IsFalse(fs.Exists(testDestinationPath));

            rt = runner.RunTask("S3Upload",
              new NameValue("AccessKeyID", accessKeyID),
              new NameValue("SecretAccessKey", secretAccessKey),
              new NameValue("SourcePath", testSourcePath),
              new NameValue("DestinationPath", testDestinationPath.ToString()),
              new NameValue("CannedACL", "public-read")
              );
            Assert.IsTrue(rt);

           // fs.Invalidate(Path.Parse("/asdf/"));
            item = fs.GetItem(testDestinationPath) as IFileItem;
            Assert.IsNotNull(item);
            Assert.AreEqual(testSourceFileInfo.Length, item.Size);
            metadata = fs.GetMetadata(testDestinationPath);

            acl = fs.GetACL(testDestinationPath);
            Assert.AreEqual(2, acl.Principals.Count);
            Assert.AreEqual(acl.Owner, acl.Principals[0]);
            permissions = acl.GetPermissions(acl.Principals[0]);
            Assert.AreEqual(1, permissions.Count);
            Assert.AreEqual(S3Constants.Permissions.FullControl, permissions[0]);

            ACLPrincipal principal = acl.Principals[1];
            Assert.AreEqual("http://acs.amazonaws.com/groups/global/AllUsers", principal.ID);
            permissions = acl.GetPermissions(principal);
            Assert.AreEqual(1, permissions.Count);
            Assert.AreEqual(S3Constants.Permissions.Read, permissions[0]);



            // normal download: file->file
            string localTestPath = @"c:\small2.zip";
            if (System.IO.File.Exists(localTestPath))
            {
                System.IO.File.Delete(localTestPath);
            }
            rt = runner.RunTask("S3Download",
               new NameValue("AccessKeyID", accessKeyID),
               new NameValue("SecretAccessKey", secretAccessKey),
               new NameValue("SourcePath", testDestinationPath.ToString()),
               new NameValue("DestinationPath", localTestPath)
               );
            Assert.IsTrue(rt);

            System.IO.FileInfo info2 = new System.IO.FileInfo(localTestPath);
            Assert.IsTrue(info2.Exists);
            Assert.AreEqual(testSourceFileInfo.Length, info2.Length);


            // normal download: file->folder
            localTestPath = @"c:\b\small.zip";
            if (System.IO.File.Exists(localTestPath))
            {
                System.IO.File.Delete(localTestPath);
            }
           rt =  runner.RunTask("S3Download",
               new NameValue("AccessKeyID", accessKeyID),
               new NameValue("SecretAccessKey", secretAccessKey),
               new NameValue("SourcePath", testDestinationPath.ToString()),
               new NameValue("DestinationPath", @"c:\b\")
               );
           Assert.IsTrue(rt);

            info2 = new System.IO.FileInfo(localTestPath);
            Assert.IsTrue(info2.Exists);
            Assert.AreEqual(testSourceFileInfo.Length, info2.Length);



            LocalFileSystem localFS = new LocalFileSystem();


            // normal download: folder->folder
            Path localTestPathPath = Path.Parse("/c:/b/contact/");
            if (localFS.Exists(localTestPathPath))
            {
                localFS.Delete(localTestPathPath);
            }
            rt = runner.RunTask("S3Download",
               new NameValue("AccessKeyID", accessKeyID),
               new NameValue("SecretAccessKey", secretAccessKey),
               new NameValue("SourcePath", "/asdf/contact/"),
               new NameValue("DestinationPath", @"c:\b\")
               );
            Assert.IsTrue(rt);

           
            Assert.IsTrue(localFS.Exists(localTestPathPath));
            //Assert.AreEqual(testSourceFileInfo.Length, info2.Length);

        }
    }
}
